#include "common.hpp"

//对应的程序，在加载的时候，会自动构建全局变量，就要调用该类的构造函数 -- 创建管道文件
//程序退出的时候，全局变量会被析构，自动调用析构函数，会自动删除管道文件
Init init; 

int main()
{
    //1.创建公共的key值
    key_t k = ftok(PATH_NAME, PROJ_ID);
    assert(k != -1);
    cout << "create key done server key : " << k << endl;

    //2.创建共享内存--建议创建全新的共享内存--因为server是通信的发起者
    int shmid = shmget(k, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666);
    assert(shmid != -1);
    cout << "create shm done shmid : " << shmid << endl;
    // sleep(10);

    //3.将指定共享内存，从自己的地址空间中关联
    char* shmaddr = (char*)shmat(shmid, nullptr, 0);
    cout << "attach shm done shmid : " << shmid << endl;
    // sleep(10);

    //这里是通信的逻辑
    //将共享内存当成一个大字符串
    //char buffer[SHM_SIZE];
    //结论1： 只要是通信双方使用shm，一方直接向共享内存中写入数据，另一方，就可以立马看到对方写入的数据。
    //       共享内存是所有进程间通信(IPC)，速度最快的！不需要过多的拷贝！！（不需要将数据给操作系统）
    //结论2： 共享内存缺乏访问控制！会带来并发问题 【如果我想一定程度的访问控制呢? 能】
    int fd = OpenFIFO(FIFO_PATH, READ);
    for (;;)
    {
        Wait(fd);

        printf("%s\n", shmaddr);
        if (strcmp(shmaddr, "quit") == 0)
        {
            break;
        }
        // sleep(1);
    }



    //4.将指定的共享内存，从自己的地址空间中取消关联
    int n = shmdt(shmaddr);
    assert(n != -1);
    (void)n;
    cout << "detach shm done shmid : " << shmid << endl;
    // sleep(10);

    //5.删除共享内存,IPC_RMID即便是有进程和当前共享内存关联，依旧删除共享内存
    n = shmctl(shmid, IPC_RMID, nullptr);
    assert(n != -1);
    (void)n;
    cout << "delete shm done shmid : " << shmid << endl;

    return 0;
}